/* CSci4061 F2012 Assignment 4
 * date: 12/1/12
 * name: Jeff Goin, Jack Jones
 * id: 2999885, 4220764 */


#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "textbuff.h"

    // pointer to list
    node *textbuff;
    /*
     * Initializes the required data structures necessary
     * for the text buffer. Additionally it opens and reads
     * file into the text buffer.
     * @params file the file to be opened and read into
     * the text buffer.
     */
    void init_textbuff(char* file){
        // open file
        FILE *f = fopen(file, "rw");
        char cur_line[LINEMAX + 2];
        node *cur_node;
        int first = 0;
	

        while (fgets(cur_line, LINEMAX + 2, f) != NULL){
            node *new_node = (node *)malloc(sizeof(node));
            new_node->data = (char *)malloc(LINEMAX);
	    if (strlen(cur_line) > 0 && cur_line[strlen(cur_line)-1] == '\n')
	        cur_line[strlen(cur_line)-1] = '\0';
            strncpy(new_node->data, cur_line, LINEMAX);
            if (first == 0){ 
                cur_node = new_node;
                textbuff = cur_node;
                first = 1;
            }
            else {
                cur_node->next = new_node;
                cur_node = cur_node->next;
            }
        }
        if (fclose(f) != 0)
			exit(0);
    }

    /*
     * Appends the everything from line
     * until a newline is reached to the
     * current text buffer. If LINEMAX is
     * reached it inserts a newline and
     * continues appending line.
     * @params line the line of text to be
     * appended
     * @returns 0 if error occurs and 1 if successful
     */
    int appendLine(char* line) {
        node *cur_node = textbuff;
	while(cur_node != NULL) {
	    cur_node = cur_node->next;
	}
	
	int len = strlen(cur_node->data);
	if (strlen(line) < LINEMAX - len) {
	    strcat(cur_node->data, line);
	}

	if (len = LINEMAX) {
	    node *new = (node *)malloc(sizeof(node));
	    new->data = (char *)malloc(LINEMAX);
	    cur_node->next = new;
	    new->next = NULL;
	    strcpy(new->data, line);
	}  
		
	node *new = (node *)malloc(sizeof(node));
	new->data = (char *)malloc(LINEMAX);
	cur_node->next = new;
	new->next = NULL;
	char *temp_line = line + (LINEMAX - len + 1);	
	strncat(cur_node->data, line, LINEMAX - len);
	strcpy(new->data, temp_line);
    }
		
			

    /*
     * Fetches line index from the buffer
     * and places it in returnLine
     * @params index line to fetch
     * returnLine pointer which will point to
     * a copy of the desired line. Memory allocated
     * with malloc.
     * @returns 0 if error occurs or 1 if successful
     */
    int getLine(int index, char** returnLine){
        node *cur_node = textbuff;
        int i = 0;
        while(i < index && cur_node != NULL){
            cur_node = cur_node->next;
            if (cur_node == NULL) return 0;
            i++;
        }
        *returnLine = cur_node->data;
        return 1;
    }
    /*
     * Inserts text into row at position col.
     * If col is zero insert at the begining of the line.
     * If the new line length is more than LINEMAX
     * then split the line at line max and insert a
     * new line in the text buffer after the current line.
     * @returns 0 if error occurs or 1 if successful
     */
    int insert(int row, int col, char text) {
        if (col > LINEMAX || col < 0)
	    return 0;
	//FILE *save = fopen("save.txt", "a");
	int i = 0;
	int full = 0;
	int size = 0;
	size = getLineLength();
	
	node *cur_node = textbuff;
				
	//if (size < 43) {
	while (i < row) {
	    if (cur_node == NULL)
	        return 0;
	    cur_node = cur_node->next;
	    i++;
	}
	//}

	/*else {
	    while (i < row + 1) {
	        if (cur_node == NULL)
		return 0;
		cur_node = cur_node->next;
		i++;
		}
		}*/				
	int len = (strlen(cur_node->data));

	if (row + 1 == size && len == LINEMAX) {
	    if (cur_node->next == NULL) {
	        node *new_node = (node *)malloc(sizeof(node));
		if (new_node == NULL) {
		    perror("Unable to allocate memory!");
		    exit(0);
		}

		new_node->data = (char *)malloc(LINEMAX);
		if (new_node->data == NULL) {
		    perror("Unable to allocate memory!");
		    exit(0);
		}
		cur_node->next = new_node;
		new_node->next = NULL;

		char temp = cur_node->data[LINEMAX - 1];
		insert(row + 1, 0, temp);
		//size++;
		len--;
	    }
	}					
	
	if (col == LINEMAX - 1 && len == LINEMAX - 1) {
	    insert(row + 1, 0, text);
	}
	
	else if (col == len) {
	    cur_node->data[col] = text;
	    cur_node->data[col + 1] = '\0';
	    return 1;
	}				  
        
	else if (len == LINEMAX) {
	    char temp = cur_node->data[LINEMAX - 1];
	    insert(row + 1, 0, temp);
	    len--;
	}

	cur_node->data[len + 1] = '\0';
	for (i = len; i > col; i--) {
	    cur_node->data[i] = cur_node->data[i - 1];
	}
	cur_node->data[col] = text;
	return 1;
	
    }
    /*
     * Returns the number of lines in the textbuffer
     */
    int getLineLength(){
        int count = 0;
        node *cur_node = textbuff;
        while (cur_node != NULL){
            count++;
            cur_node = cur_node->next;
        }
        return count;
    }
    /*
     * Delete the line index
     * @returns 0 if error otherwise returns 1
     */
    int deleteLine(int index){
        node *cur_node = textbuff;
        node *prev_node, *temp;
        int i = 0; 
        if (index == 0){
            if (textbuff->next == NULL) return 0; 
            textbuff = textbuff->next;
            free(cur_node->data);
            free(cur_node);
            return 1;
        }
        else {
            while (i < index && cur_node != NULL){
                prev_node = cur_node;  
                cur_node = cur_node->next;
                i++;
            }
            temp = cur_node;
            cur_node = cur_node->next;
            prev_node->next = cur_node;
            free(temp->data);
            free(temp);
        }
    }
    /*
     * Delete a single characer at (row,col)
     * from the text buffer
     * @returns 0 if error otherwise returns 1
     */
    int deleteCharacter(int row, int col) {
        if (col > LINEMAX || col < 0)
	    return 0;
      
	node *cur_node = textbuff;
	int i = 0;
	while (i < row) {
	    if (cur_node == NULL)
	        return 0;
	    cur_node = cur_node->next;
	    i++;
	}
	i = col;
	while (i < strlen(cur_node->data)) {
	    cur_node->data[i] = cur_node->data[i+1];
	    i++;
	}
	return 1;
  }

    /*
     * Cleans up the buffer sets the buffer length
     * to -1 represinting that the buffer is invalid
     */
    void deleteBuffer(){
        node *cur_node = textbuff->next;
        node *temp;
        while (cur_node != NULL){
            temp = cur_node;
            cur_node = cur_node->next;
            free(temp->data);
            free(temp);
        }
    }



/*int main(int argc, char **argv){
     char *file = argv[1];
     
     init_textbuff(file);
     node *cur_node = textbuff;
     while (cur_node != NULL){
         printf("\nLine: %s", cur_node->data);
         cur_node = cur_node->next;
     }

     printf("getLineLength %d\n", getLineLength());
     char *line;
     getLine(0, &line);
     printf("getLine: %s\n", line);

     insert(5, 50, '.');
     insert(5, 98, '.');
     insert(5, 3, '.');
     printf("Delete line test\n");

     cur_node = textbuff;
     while (cur_node != NULL){
       printf("\nLine: %s", cur_node->data);
       cur_node = cur_node->next;
     }
     deleteBuffer();
}*/
